package divestoclimb.checklist;

import java.text.ParseException;
import java.util.Date;

import divestoclimb.checklist.storage.DbAdapter;
import divestoclimb.util.FriendlyDate;

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.util.Log;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.CursorAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;
import android.widget.AdapterView.AdapterContextMenuInfo;

public class ChecklistList extends AbsListByCategory implements SimpleCursorAdapter.ViewBinder {
	
	private static final int DIALOG_CONFIRM_DELETE = 1;
	private static final int SORT_MODE_ALPHA = 0;
	private static final int SORT_MODE_DATE = 1;
	
	private int mSortMode;						// The numeric sort mode for list items
	private boolean mCompletionState;			// Whether to display complete or
												// incomplete checklists
	
	private long mSelectedItem;					// Used to track a selected item
												// from a context menu if we need
												// to wait for confirmation

	@Override
	protected void onCreate(Bundle icicle) {
		super.onCreate(icicle);

		// Register the List for a context menu
		registerForContextMenu(getListView());

		Bundle params = icicle != null? icicle: getIntent().getExtras();
		if(params != null) {
			mCompletionState = params.getBoolean("completed");
			mSortMode = params.getInt("sort");	// Default is 0; SORT_MODE_ALPHA
		} else {
			mCompletionState = false;
			mSortMode = SORT_MODE_ALPHA;
		}
	}

	@Override
	protected void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
		outState.putBoolean("completed", mCompletionState);
		outState.putInt("sort", mSortMode);
	}

	/**
	 * Perform a query to get the Cursor to use for our ListAdapter based on the
	 * current values of mSortMode and mCategoryId. This is called during initialization
	 * and any time the query behind the cursor needs to change.
	 * 
	 * @return A Cursor containing the results from the new query
	 */
	protected Cursor buildCursor() {
		String sort;
		switch(mSortMode) {
		case SORT_MODE_ALPHA:
			sort = DbAdapter.KEY_CHECKLIST_NAME;
			break;
		case SORT_MODE_DATE:
			sort = mCompletionState? DbAdapter.KEY_CHECKLIST_WHENCOMPLETED:
				DbAdapter.KEY_CHECKLIST_WHENSTARTED;
			sort += " DESC";
			break;
		default:
			sort = null;
		}
		long c = getCategoryId();
		return getDbHelper().fetchChecklists(sort, mCompletionState,
				c == SelectCategory.ID_ALL? -1: c);
	}

	// Implementation of SimpleCursorAdapter.ViewBinder
	public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
		if(view instanceof TextView) {
			final int dateIndex = cursor.getColumnIndexOrThrow(mCompletionState?
					DbAdapter.KEY_CHECKLIST_WHENCOMPLETED:
					DbAdapter.KEY_CHECKLIST_WHENSTARTED);
			if(columnIndex == dateIndex) {
				String prefix = getString(mCompletionState? R.string.completed: R.string.started);
				// A bug was fixed in 1.0.2 that caused restored checklists to get
				// NULL set for the start and complete dates. This code prevents
				// a NullPointerException if we encounter a checklist that was
				// restored from an earlier version.
				String val = cursor.getString(columnIndex), dateString = getString(R.string.unknown);
				if(val != null) {
					try {
						Date d = DbAdapter.getDateFormatGMT().parse(cursor.getString(columnIndex));
						dateString = FriendlyDate.format(d);
					} catch(ParseException e) {
						// Do nothing, it's not possible
					}
				}
				((TextView)view).setText(String.format(prefix, dateString));
				return true;
			}
		}
		return false;
	}
	
	/**
	 * Start an Activity to fill out a checklist
	 * 
	 * @param template_id The database ID of the Template to pass to the Activity
	 */
	private void fillChecklist(long checklist_id) {
		Intent i = new Intent(this, FillChecklist.class);
		i.putExtra(DbAdapter.KEY_CHECKLIST_ID, checklist_id);
		startActivityForResult(i, 0);
	}

	private void editChecklist(long checklist_id) {
		Intent i = new Intent(this, EditChecklist.class);
		i.putExtra(DbAdapter.KEY_TEMPLATE_ID, checklist_id);
		startActivityForResult(i, 0);
	}

	private void deleteChecklist(long checklist_id) {
		getDbHelper().deleteChecklist(checklist_id);
		((CursorAdapter)getListView().getAdapter()).getCursor().requery();
	}
	
	@Override
	protected Dialog onCreateDialog(int id) {
		switch(id) {
		case DIALOG_CONFIRM_DELETE:
			return new AlertDialog.Builder(this)
			.setIcon(android.R.drawable.ic_dialog_alert)
			.setTitle(R.string.confirm_delete)
			.setMessage(R.string.confirm_checklist_delete)
			.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
				public void onClick(DialogInterface dialog, int whichButton) {
					deleteChecklist(mSelectedItem);
				}
			})
			.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
				public void onClick(DialogInterface dialog, int whichButton) {
					// Do nothing
				}
			})
			.create();
		}
		return null;
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.checklist_list, menu);
		return true;
	}
	
	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		super.onPrepareOptionsMenu(menu);
		menu.findItem(R.id.sort_by_name).setVisible(mSortMode != SORT_MODE_ALPHA);
		menu.findItem(R.id.sort_by_date).setVisible(mSortMode != SORT_MODE_DATE);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch(item.getItemId()) {
		case R.id.new_checklist:
			Intent i = new Intent(this, TemplateList.class);
			i.putExtra(TemplateList.KEY_ONCLICK_ACTION, TemplateList.ACTION_NEW_CHECKLIST);
			startActivity(i);
			break;
		case R.id.sort_by_name:
			mSortMode = SORT_MODE_ALPHA;
			rebuildCursor();
			break;
		case R.id.sort_by_date:
			mSortMode = SORT_MODE_DATE;
			rebuildCursor();
		}
		return super.onOptionsItemSelected(item);
	}

	@Override
	public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
		super.onCreateContextMenu(menu, v, menuInfo);
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.checklist_list_context, menu);
	}

	@Override
	public boolean onContextItemSelected(MenuItem item) {
		AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
		switch(item.getItemId()) {
		case R.id.fill:
			fillChecklist(info.id);
			break;
		case R.id.info:
			editChecklist(info.id);
			break;
		case R.id.delete:
			mSelectedItem=info.id;
			showDialog(DIALOG_CONFIRM_DELETE);
			break;
		}
		
		return super.onContextItemSelected(item);
	}

	@Override
	protected void onListItemClick(ListView l, View v, int position, long id) {
		super.onListItemClick(l, v, position, id);
		if (position >= 0) {
			Cursor c = (Cursor) l.getItemAtPosition(position);
			long selected_checklist=c.getLong(c.getColumnIndexOrThrow(DbAdapter.KEY_TEMPLATE_ID));
			fillChecklist(selected_checklist);
		}
	}

	@Override
	protected ListAdapter buildCursorAdapter(Cursor c) {
		// If we're showing completed checklists, show the date of completion.
		// Otherwise, show the date the checklist was created
		final String date_field = mCompletionState?
				DbAdapter.KEY_CHECKLIST_WHENCOMPLETED:
				DbAdapter.KEY_CHECKLIST_WHENSTARTED;

		SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
				R.layout.checklist_list_item,
				c,
				new String[] { DbAdapter.KEY_CHECKLIST_NAME, date_field },
				new int[] { android.R.id.text1, R.id.date });
		adapter.setViewBinder(this);
		setListAdapter(adapter);
		return adapter;
	}

}